import calendar
import os
import tkinter as tk
from datetime import datetime, timedelta
from tkinter import ttk

import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib as mpl
from matplotlib.font_manager import FontProperties

from models.task_models import TaskStatus


class ReportView:
    """报表分析视图 - 支持独立窗口和内嵌模式"""

    def __init__(self, parent, db, container=None):
        """
        初始化报表分析视图
        :param parent: 父窗口（用于独立模式）
        :param db: 数据库实例
        :param container: 内嵌模式的容器（可选）
        """
        self.db = db

        # 根据是否提供容器决定使用独立窗口还是内嵌模式
        if container:
            # 内嵌模式
            self.frame = ttk.Frame(container)
            self.frame.pack(fill=tk.BOTH, expand=True)
            self.create_widgets(self.frame)
        else:
            # 独立窗口模式
            self.top = tk.Toplevel(parent)
            self.top.title("任务报表分析")
            self.top.geometry("1200x800")
            self.top.transient(parent)
            self.top.grab_set()
            self.top.resizable(True, True)
            self.frame = self.top
            self.create_widgets(self.top)

        # 配置Matplotlib字体
        self.configure_matplotlib_font()
        # 加载数据
        self.load_data()

    def create_widgets(self, parent):
        """创建界面控件"""
        # 创建主框架
        main_frame = ttk.Frame(parent, padding=15)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 标题和选项卡
        ttk.Label(
            main_frame,
            text="任务报表分析",
            font=("Arial", 16, "bold")
        ).pack(pady=(0, 15))

        # 创建选项卡
        self.notebook = ttk.Notebook(main_frame)
        self.notebook.pack(fill=tk.BOTH, expand=True)

        # 创建各报表页
        self.create_summary_tab()
        self.create_weekly_tab()
        self.create_monthly_tab()
        self.create_yearly_tab()

    def configure_matplotlib_font(self):
        """配置Matplotlib使用支持中文的字体"""
        # 获取系统支持中文的字体
        chinese_fonts = ['SimHei', 'Microsoft YaHei', 'KaiTi', 'SimSun',
                         'FangSong', 'STXihei', 'STKaiti', 'STSong']

        # 检查系统可用的中文
        available_fonts = [f for f in chinese_fonts
                           if any(f in font.name for font in mpl.font_manager.fontManager.ttflist)]

        if available_fonts:
            # 设置默认字体
            plt.rcParams['font.sans-serif'] = available_fonts
            plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
        else:
            # 如果没有中文，使用支持中文的字体路径
            try:
                # 这里添加一个常见的中文字体路径作为后备方案
                font_path = 'C:/Windows/Fonts/simhei.ttf'  # Windows 路径
                if not os.path.exists(font_path):
                    font_path = '/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf'  # Linux 路径

                if os.path.exists(font_path):
                    prop = FontProperties(fname=font_path)
                    plt.rcParams['font.family'] = prop.get_name()
                    plt.rcParams['axes.unicode_minus'] = False
            except:
                pass

    def create_summary_tab(self):
        """创建概览报表页"""
        tab = ttk.Frame(self.notebook)
        self.notebook.add(tab, text="概览")

        # 概览数据框架
        summary_frame = ttk.LabelFrame(tab, text="任务概览")
        summary_frame.pack(fill=tk.X, padx=10, pady=10)

        # 概览数据
        ttk.Label(summary_frame, text="总任务数:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)
        self.total_label = ttk.Label(summary_frame, text="0")
        self.total_label.grid(row=0, column=1, sticky=tk.W, padx=5, pady=5)

        ttk.Label(summary_frame, text="已完成:").grid(row=1, column=0, sticky=tk.W, padx=5, pady=5)
        self.completed_label = ttk.Label(summary_frame, text="0")
        self.completed_label.grid(row=1, column=1, sticky=tk.W, padx=5, pady=5)

        ttk.Label(summary_frame, text="未完成:").grid(row=2, column=0, sticky=tk.W, padx=5, pady=5)
        self.pending_label = ttk.Label(summary_frame, text="0")
        self.pending_label.grid(row=2, column=1, sticky=tk.W, padx=5, pady=5)

        ttk.Label(summary_frame, text="已过期:").grid(row=3, column=0, sticky=tk.W, padx=5, pady=5)
        self.expired_label = ttk.Label(summary_frame, text="0")
        self.expired_label.grid(row=3, column=1, sticky=tk.W, padx=5, pady=5)

        ttk.Label(summary_frame, text="完成率:").grid(row=0, column=2, sticky=tk.W, padx=5, pady=5)
        self.completion_rate_label = ttk.Label(summary_frame, text="0%")
        self.completion_rate_label.grid(row=0, column=3, sticky=tk.W, padx=5, pady=5)

        ttk.Label(summary_frame, text="延期率:").grid(row=1, column=2, sticky=tk.W, padx=5, pady=5)
        self.delay_rate_label = ttk.Label(summary_frame, text="0%")
        self.delay_rate_label.grid(row=1, column=3, sticky=tk.W, padx=5, pady=5)

        # 状态分布图
        status_frame = ttk.LabelFrame(tab, text="任务状态分布")
        status_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        self.status_fig, self.status_ax = plt.subplots(figsize=(6, 4))
        self.status_canvas = FigureCanvasTkAgg(self.status_fig, master=status_frame)
        self.status_canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)

    def create_weekly_tab(self):
        """创建周报表页"""
        tab = ttk.Frame(self.notebook)
        self.notebook.add(tab, text="周报")

        # 周选择器
        week_frame = ttk.Frame(tab)
        week_frame.pack(fill=tk.X, padx=10, pady=10)

        ttk.Label(week_frame, text="选择周:").pack(side=tk.LEFT, padx=(0, 5))

        self.week_var = tk.StringVar()
        self.week_combo = ttk.Combobox(
            week_frame,
            textvariable=self.week_var,
            state="readonly",
            width=20
        )
        self.week_combo.pack(side=tk.LEFT, padx=(0, 10))
        self.week_combo.bind("<<ComboboxSelected>>", self.on_week_select)

        # 周数据图表
        weekly_frame = ttk.LabelFrame(tab, text="周任务统计")
        weekly_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        self.weekly_fig, self.weekly_ax = plt.subplots(figsize=(8, 5))
        self.weekly_canvas = FigureCanvasTkAgg(self.weekly_fig, master=weekly_frame)
        self.weekly_canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)

    def create_monthly_tab(self):
        """创建月报表页"""
        tab = ttk.Frame(self.notebook)
        self.notebook.add(tab, text="月报")

        # 月选择器
        month_frame = ttk.Frame(tab)
        month_frame.pack(fill=tk.X, padx=10, pady=10)

        ttk.Label(month_frame, text="选择月份:").pack(side=tk.LEFT, padx=(0, 5))

        self.month_var = tk.StringVar()
        self.month_combo = ttk.Combobox(
            month_frame,
            textvariable=self.month_var,
            state="readonly",
            width=20
        )
        self.month_combo.pack(side=tk.LEFT, padx=(0, 10))
        self.month_combo.bind("<<ComboboxSelected>>", self.on_month_select)

        # 月数据图表
        monthly_frame = ttk.LabelFrame(tab, text="月任务统计")
        monthly_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        self.monthly_fig, self.monthly_ax = plt.subplots(figsize=(8, 5))
        self.monthly_canvas = FigureCanvasTkAgg(self.monthly_fig, master=monthly_frame)
        self.monthly_canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)

    def create_yearly_tab(self):
        """创建年报表页"""
        tab = ttk.Frame(self.notebook)
        self.notebook.add(tab, text="年报")

        # 年选择器
        year_frame = ttk.Frame(tab)
        year_frame.pack(fill=tk.X, padx=10, pady=10)

        ttk.Label(year_frame, text="选择年份:").pack(side=tk.LEFT, padx=(0, 5))

        self.year_var = tk.StringVar()
        self.year_combo = ttk.Combobox(
            year_frame,
            textvariable=self.year_var,
            state="readonly",
            width=20
        )
        self.year_combo.pack(side=tk.LEFT, padx=(0, 10))
        self.year_combo.bind("<<ComboboxSelected>>", self.on_year_select)

        # 年数据图表
        yearly_frame = ttk.LabelFrame(tab, text="年任务统计")
        yearly_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        self.yearly_fig, self.yearly_ax = plt.subplots(figsize=(8, 5))
        self.yearly_canvas = FigureCanvasTkAgg(self.yearly_fig, master=yearly_frame)
        self.yearly_canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)

    def load_data(self):
        """加载报表数据"""
        tasks = self.db.get_all_tasks()

        # 概览数据
        total = len(tasks)
        completed = len([t for t in tasks if t.status == TaskStatus.COMPLETED])
        pending = len([t for t in tasks if t.status == TaskStatus.PENDING])
        expired = len([t for t in tasks if t.status == TaskStatus.EXPIRED])

        completion_rate = (completed / total * 100) if total > 0 else 0
        delay_rate = (expired / total * 100) if total > 0 else 0

        self.total_label.config(text=str(total))
        self.completed_label.config(text=str(completed))
        self.pending_label.config(text=str(pending))
        self.expired_label.config(text=str(expired))
        self.completion_rate_label.config(text=f"{completion_rate:.1f}%")
        self.delay_rate_label.config(text=f"{delay_rate:.1f}%")

        # 状态分布图
        self.status_ax.clear()
        status_counts = {
            "已完成": completed,
            "未完成": pending,
            "已过期": expired
        }
        self.status_ax.pie(
            status_counts.values(),
            labels=status_counts.keys(),
            autopct='%1.1f%%',
            startangle=90,
            colors=['#4CAF50', '#FFC107', '#F44336']
        )
        self.status_ax.set_title("任务状态分布")
        self.status_canvas.draw()

        # 加载周、月、年数据
        self.load_week_data()
        self.load_month_data()
        self.load_year_data()

    def load_week_data(self):
        """加载周数据"""
        # 获取最近12周的周数
        weeks = []
        current_date = datetime.now()
        for i in range(12):
            week_start = current_date - timedelta(days=current_date.weekday() + 7 * i)
            week_end = week_start + timedelta(days=6)
            weeks.append(f"{week_start.strftime('%Y-%m-%d')} 至 {week_end.strftime('%Y-%m-%d')}")

        self.week_combo["values"] = weeks
        if weeks:
            self.week_var.set(weeks[0])
            self.update_weekly_chart(weeks[0])

    def on_week_select(self, event):
        """周选择事件"""
        self.update_weekly_chart(self.week_var.get())

    def update_weekly_chart(self, week_range):
        """更新周图表"""
        # 解析周范围
        start_str, end_str = week_range.split(" 至 ")
        start_date = datetime.strptime(start_str, "%Y-%m-%d").date()
        end_date = datetime.strptime(end_str, "%Y-%m-%d").date()

        # 获取该周的任务
        tasks = self.db.get_all_tasks()
        week_tasks = [t for t in tasks if start_date <= t.due_date <= end_date]

        # 按状态分组
        status_counts = {
            "已完成": 0,
            "未完成": 0,
            "已过期": 0
        }

        for task in week_tasks:
            if task.status == TaskStatus.COMPLETED:
                status_counts["已完成"] += 1
            elif task.status == TaskStatus.PENDING:
                status_counts["未完成"] += 1
            elif task.status == TaskStatus.EXPIRED:
                status_counts["已过期"] += 1

        # 绘制图表
        self.weekly_ax.clear()
        days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]

        # 按天统计任务数
        daily_counts = {day: 0 for day in days}
        for task in week_tasks:
            weekday = task.due_date.weekday()
            daily_counts[days[weekday]] += 1

        self.weekly_ax.bar(days, daily_counts.values(), color='#2196F3')
        self.weekly_ax.set_title(f"周任务分布 ({week_range})")
        self.weekly_ax.set_xlabel("星期")
        self.weekly_ax.set_ylabel("任务数量")
        self.weekly_canvas.draw()

    def load_month_data(self):
        """加载月数据"""
        # 获取最近12个月
        months = []
        current_date = datetime.now()
        for i in range(12):
            month_date = current_date - timedelta(days=30 * i)
            months.append(month_date.strftime("%Y-%m"))

        self.month_combo["values"] = months
        if months:
            self.month_var.set(months[0])
            self.update_monthly_chart(months[0])

    def on_month_select(self, event):
        """月选择事件"""
        self.update_monthly_chart(self.month_var.get())

    def update_monthly_chart(self, month_str):
        """更新月图表"""
        year, month = map(int, month_str.split('-'))

        # 获取该月的任务
        tasks = self.db.get_all_tasks()
        month_tasks = [t for t in tasks if t.due_date.year == year and t.due_date.month == month]

        # 按状态分组
        status_counts = {
            "已完成": 0,
            "未完成": 0,
            "已过期": 0
        }

        for task in month_tasks:
            if task.status == TaskStatus.COMPLETED:
                status_counts["已完成"] += 1
            elif task.status == TaskStatus.PENDING:
                status_counts["未完成"] += 1
            elif task.status == TaskStatus.EXPIRED:
                status_counts["已过期"] += 1

        # 绘制图表
        self.monthly_ax.clear()

        # 按天统计任务数
        _, num_days = calendar.monthrange(year, month)
        daily_counts = {day: 0 for day in range(1, num_days + 1)}

        for task in month_tasks:
            day = task.due_date.day
            if 1 <= day <= num_days:
                daily_counts[day] += 1

        self.monthly_ax.bar(
            list(daily_counts.keys()),
            list(daily_counts.values()),
            color='#2196F3'
        )
        self.monthly_ax.set_title(f"月任务分布 ({month_str})")
        self.monthly_ax.set_xlabel("日期")
        self.monthly_ax.set_ylabel("任务数量")
        self.monthly_canvas.draw()

    def load_year_data(self):
        """加载年数据"""
        # 获取最近5年
        years = []
        current_year = datetime.now().year
        for i in range(5):
            years.append(str(current_year - i))

        self.year_combo["values"] = years
        if years:
            self.year_var.set(years[0])
            self.update_yearly_chart(years[0])

    def on_year_select(self, event):
        """年选择事件"""
        self.update_yearly_chart(self.year_var.get())

    def update_yearly_chart(self, year_str):
        """更新年图表"""
        year = int(year_str)

        # 获取该年的任务
        tasks = self.db.get_all_tasks()
        year_tasks = [t for t in tasks if t.due_date.year == year]

        # 按状态分组
        status_counts = {
            "已完成": 0,
            "未完成": 0,
            "已过期": 0
        }

        for task in year_tasks:
            if task.status == TaskStatus.COMPLETED:
                status_counts["已完成"] += 1
            elif task.status == TaskStatus.PENDING:
                status_counts["未完成"] += 1
            elif task.status == TaskStatus.EXPIRED:
                status_counts["已过期"] += 1

        # 绘制图表
        self.yearly_ax.clear()

        # 按月统计任务数
        monthly_counts = {month: 0 for month in range(1, 13)}

        for task in year_tasks:
            month = task.due_date.month
            monthly_counts[month] += 1

        month_names = [calendar.month_abbr[i] for i in range(1, 13)]

        self.yearly_ax.bar(
            month_names,
            [monthly_counts[m] for m in range(1, 13)],
            color='#2196F3'
        )
        self.yearly_ax.set_title(f"年任务分布 ({year_str})")
        self.yearly_ax.set_xlabel("月份")
        self.yearly_ax.set_ylabel("任务数量")
        self.yearly_canvas.draw()